package com.knowledge.plus.深拷贝和浅拷贝;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.SerializationUtils;

import java.io.*;

/**
 * @author TPF
 * @since 2024/11/18
 */
public class SerializationDemo {

    /**
     * 通过将对象序列化为字节流，然后再反序列化为新的对象，可以实现深拷贝。这种方法适用于实现了 Serializable 接口的对象。
     */
    public static <T> T deepClone(T obj) throws IOException, ClassNotFoundException {
        // 序列化
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(obj);

        // 反序列化
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        return (T) in.readObject();
    }

    @SneakyThrows
    public static void main(String[] args) {
        SeriaAddress address = new SeriaAddress("浙江省", "杭州市");
        SeriaPerson person1 = new SeriaPerson("张珊", address);

        SeriaPerson person2 = deepClone(person1);
        System.out.println(person1.getAddress() == person2.getAddress());  // 结果：false

        /*
         * 第三方库
         */
        SeriaPerson person3 = SerializationUtils.clone(person1);
        System.out.println(person1.getAddress() == person3.getAddress());  // 结果：false

    }

}

@Data
@NoArgsConstructor
@AllArgsConstructor
class SeriaPerson implements Serializable {
    private static final long serialVersionUID = 1L;

    /* 姓名 */
    private String name;
    /* 地址 */
    private SeriaAddress address;

}

@Data
@NoArgsConstructor
@AllArgsConstructor
class SeriaAddress implements Serializable {
    private static final long serialVersionUID = 1L;

    /* 省 */
    private String province;
    /* 市 */
    private String city;

}
